/* eslint-disable no-use-before-define */
/*
 * @Description: 建立websocket链接
 * @Author: liushuang
 * @Date: 2022-08-12 16:56:52
 * @LastEditTime: 2023-03-03 15:46:47
 */
import { ElMessage } from 'element-plus'

class WebSocketConnection {
  constructor(url) {
    this.Socket = ''
    this.setIntervalWesocketPush = null
    this.socketUrl = ''
    this.url = url
  }

  /**
   * 建立websocket连接
   */
  createSocket = () => {
    this.Socket && this.Socket.close()
    if (!this.Socket) {
      if (this.url && !this.socketUrl) {
        this.socketUrl = this.url
      }
      try {
        this.Socket = new WebSocket(this.url)
        this.Socket.onopen = this.onopenWS.bind(this)
        this.Socket.onmessage = this.onmessageWS.bind(this)
        this.Socket.onerror = this.onerrorWS.bind(this)
        this.Socket.onclose = this.oncloseWS.bind(this)
      } catch (error) {
        ElMessage({
          type: 'error',
          message: `websocket连接错误 ${error}`
        })
      }
    } else {
      console.log('websocket已连接')
    }
  }

  /** 打开WS之后发送心跳 */
  onopenWS = () => {
    this.sendPing()
  }

  /** 连接失败重连 */
  onerrorWS = () => {
    if (this.Socket && this.Socket.readyState !== WebSocket.CLOSED) {
      this.Socket.close()
    }
    clearInterval(this.setIntervalWesocketPush)
    console.log('连接失败重连中')
    setTimeout(() => {
      this.createSocket()
    }, 1000)
  }

  /** WS数据接收统一处理 */
  // eslint-disable-next-line class-methods-use-this
  onmessageWS = (e) => {
    window.dispatchEvent(
      new CustomEvent('onmessageWS', {
        detail: {
          data: e.data
        }
      })
    )
  }

  /**
   * 发送数据但连接未建立时进行处理等待重发
   * @param {any} message 需要发送的数据
   */
  connecting = (message) => {
    setTimeout(() => {
      if (this.Socket.readyState === 0) {
        this.connecting(message)
      } else {
        this.Socket.send(JSON.stringify(message))
      }
    }, 1000)
  }

  /**
   * 发送数据
   * @param {any} message 需要发送的数据
   */
  sendWSPush = (message) => {
    if (this.Socket !== null && this.Socket.readyState === 3) {
      this.Socket.close()
      this.createSocket()
    } else if (this.Socket.readyState === 1) {
      this.Socket.send(JSON.stringify(message))
    } else if (this.Socket.readyState === 0) {
      this.connecting(message)
    }
  }

  /** 断开重连 */
  oncloseWS = () => {
    if (this.Socket && this.Socket.readyState !== WebSocket.CLOSED) {
      this.Socket.close()
    }
    clearInterval(this.setIntervalWesocketPush)
    console.log('websocket已断开....正在尝试重连')
    setTimeout(() => {
      this.createSocket()
    }, 1000)
  }

  /** 发送心跳
   * @param {number} time 心跳间隔毫秒 默认5000
   * @param {string} ping 心跳名称 默认字符串ping
   */
  sendPing = (time = 5000, ping = 'ping') => {
    clearInterval(this.setIntervalWesocketPush)
    this.Socket.send(ping)
    this.setIntervalWesocketPush = setInterval(() => {
      this.Socket.send(ping)
    }, time)
  }
}

export default WebSocketConnection
